//
//  GlobalService.m
//  upnpxdemo
//
//  Created by 赵帅 on 13-9-12.
//  Copyright (c) 2013年 wiimu.inc. All rights reserved.
//

#import "GlobalService.h"
#import "IPAddress.h"
#include <arpa/inet.h>
#import "HTTPServer.h"

@interface GlobalService()
{
    HTTPServer *httpServer;
    
    NSMutableArray * serviceArray;
    
    dispatch_semaphore_t semaphore;
}

@end

@implementation GlobalService

static GlobalService *sharedObj = nil;

+(GlobalService*)sharedInstance{
    if (sharedObj == nil) {
        sharedObj = [[super allocWithZone:NULL]init];
    }
    return sharedObj;
}

+ (id)allocWithZone:(NSZone *)zone{
    return [self sharedInstance];//返回单例
}

- (id)copyWithZone:(NSZone*)zone{
    return self;
}

-(id)init
{
    self = [super init];
    if(self)
    {
        serviceArray = [NSMutableArray array];
        semaphore = dispatch_semaphore_create(1);
    }
    return self;
}

#pragma mark -
#pragma mark service interface
-(void)confirmDownloadUpdate:(id<serviceConfirmDownloadUpdateDelegate>)handler;
{
    NSDictionary * dic = [NSDictionary dictionaryWithObject:[GlobalInfo sharedInstance].currentBaseURL forKey:@"baseurl"];
    serviceConfirmDownloadUpdate * service = [[serviceConfirmDownloadUpdate alloc] initWithDelegate:handler];
    [service sendRequest:dic];
    [self addNewService:service];
}

-(void)getUpdateState:(id<serviceGetUpdateStatusDelegate>)handler
{
    NSDictionary * dic = [NSDictionary dictionaryWithObject:[GlobalInfo sharedInstance].currentBaseURL forKey:@"baseurl"];
    serviceGetUpdateStatus * service = [[serviceGetUpdateStatus alloc] initWithDelegate:handler];
    [service sendRequest:dic];
    [self addNewService:service];
}

-(void)confirmUpdate:(id<serviceConfirmUpdateDelegate>)handler
{
    NSDictionary * dic = [NSDictionary dictionaryWithObject:[GlobalInfo sharedInstance].currentBaseURL forKey:@"baseurl"];
    serviceConfirmUpdate * service = [[serviceConfirmUpdate alloc] initWithDelegate:handler];
    [service sendRequest:dic];
    [self addNewService:service];
}

-(void)getWifiList:(id<serviceGetWifiListDelegate>)handler
{
    NSDictionary * dic = [NSDictionary dictionaryWithObject:[GlobalInfo sharedInstance].currentBaseURL forKey:@"baseurl"];
    serviceGetWifiList * service = [[serviceGetWifiList alloc] initWithDelegate:handler];
    [service sendRequest:dic];
    [self addNewService:service];
}

-(void)getDeviceInfo:(id<serviceGetDeviceInfoDelegate>)handler url:(NSString *)url
{
    NSDictionary * dic = [NSDictionary dictionaryWithObject:url forKey:@"baseurl"];
    serviceGetDeviceInfo * service = [[serviceGetDeviceInfo alloc] initWithDelegate:handler];
    [service sendRequest:dic];
    [self addNewService:service];
}

-(void)getCurrentConnectedDevice:(id<serviceGetCurrentConnectedDeviceDelegate>)handler
{
    NSDictionary * dic = [NSDictionary dictionaryWithObject:[GlobalInfo sharedInstance].currentBaseURL forKey:@"baseurl"];
    serviceGetCurrentConnectedDevice * service = [[serviceGetCurrentConnectedDevice alloc] initWithDelegate:handler];
    [service sendRequest:dic];
    [self addNewService:service];
}

-(void)connectToWifi:(id<serviceConnectToWifiDelegate>)handler withSsid:(NSString *)ssid andAuth:(NSString *)auth andPass:(NSString *)password andChannel:(NSString *)channel andEncrypt:(NSString *)encrypt
{
    NSDictionary * dic = [NSDictionary dictionaryWithObjectsAndKeys:[GlobalInfo sharedInstance].currentBaseURL,@"baseurl",ssid,@"ssid",auth,@"auth",password,@"password",channel,@"channel",encrypt,@"encrypt", nil];
    serviceConnectToWifi * service = [[serviceConnectToWifi alloc] initWithDelegate:handler];
    [service sendRequest:dic];
    [self addNewService:service];
}

-(void)getWifiConnectStatus:(id<serviceGetWifiConnectStatusDelegate>)handler
{
    NSDictionary * dic = [NSDictionary dictionaryWithObject:[GlobalInfo sharedInstance].currentBaseURL forKey:@"baseurl"];
    serviceGetWifiConnectStatus * service = [[serviceGetWifiConnectStatus alloc] initWithDelegate:handler];
    [service sendRequest:dic];
    [self addNewService:service];
}

-(void)getPlayerStatus:(id<serviceGetPlayerStatusDelegate>)handler
{
    NSDictionary * dic = [NSDictionary dictionaryWithObject:[GlobalInfo sharedInstance].currentBaseURL forKey:@"baseurl"];
    serviceGetPlayerStatus * service = [[serviceGetPlayerStatus alloc] initWithDelegate:handler];
    [service sendRequest:dic];
    [self addNewService:service];
}

-(void)playControl:(id<servicePlayControlDelegate>)handler withCommand:(NSString *)command
{
    NSDictionary * dic = [NSDictionary dictionaryWithObjectsAndKeys:[GlobalInfo sharedInstance].currentBaseURL,@"baseurl",command,@"command", nil];
    
    servicePlayControl * service = [[servicePlayControl alloc] initWithDelegate:handler];
    [service sendRequest:dic];
    [self addNewService:service];
}

-(void)changeVolume:(id<serviceChangeVolumeDelegate>)handler withVol:(float)volume
{
    NSDictionary * dic = [NSDictionary dictionaryWithObjectsAndKeys:[GlobalInfo sharedInstance].currentBaseURL,@"baseurl",[NSString stringWithFormat:@"%d",(int)(volume*100)],@"volume", nil];
    
    serviceChangeVolume * service = [[serviceChangeVolume alloc] initWithDelegate:handler];
    [service sendRequest:dic];
    [self addNewService:service];
}

-(void)playSeek:(id<servicePlaySeekDelegate>)handler seekTo:(NSString *)pos
{
    NSDictionary * dic = [NSDictionary dictionaryWithObjectsAndKeys:[GlobalInfo sharedInstance].currentBaseURL,@"baseurl",pos,@"curpos", nil];
    
    servicePlaySeek * service = [[servicePlaySeek alloc] initWithDelegate:handler];
    [service sendRequest:dic];
    [self addNewService:service];
}

-(void)resetDevice:(id<serviceResetDeviceDelegate>)handler
{
    NSDictionary * dic = [NSDictionary dictionaryWithObject:[GlobalInfo sharedInstance].currentBaseURL forKey:@"baseurl"];
    serviceResetDevice * service = [[serviceResetDevice alloc] initWithDelegate:handler];
    [service sendRequest:dic];
    [self addNewService:service];
}

-(void)beginCheckUpdate:(id<serviceBeginCheckUpdateDelegate>)handler
{
    NSDictionary * dic = [NSDictionary dictionaryWithObject:[GlobalInfo sharedInstance].currentBaseURL forKey:@"baseurl"];
    serviceBeginCheckUpdate * service = [[serviceBeginCheckUpdate alloc] initWithDelegate:handler];
    [service sendRequest:dic];
    [self addNewService:service];
}

-(void)rebootDevice:(id<serviceRebootDeviceDelegate>)handler
{
    NSDictionary * dic = [NSDictionary dictionaryWithObject:[GlobalInfo sharedInstance].currentBaseURL forKey:@"baseurl"];
    serviceRebootDevice * service = [[serviceRebootDevice alloc] initWithDelegate:handler];
    [service sendRequest:dic];
    [self addNewService:service];
}

-(void)setNewSSID:(id<serviceSetSSIDDelegate>)handler andNewSSID:(NSString *)newID
{
    NSDictionary * dic = [NSDictionary dictionaryWithObjectsAndKeys:[GlobalInfo sharedInstance].currentBaseURL,@"baseurl",newID,@"newssid", nil];
    serviceSetSSID * service = [[serviceSetSSID alloc] initWithDelegate:handler];
    [service sendRequest:dic];
    [self addNewService:service];
}

-(void)setNewPass:(id<serviceSetPassDelegate>)handler andNewPass:(NSString *)pass
{
    NSDictionary * dic = [NSDictionary dictionaryWithObjectsAndKeys:[GlobalInfo sharedInstance].currentBaseURL,@"baseurl",pass,@"pass", nil];
    serviceSetPass * service = [[serviceSetPass alloc] initWithDelegate:handler];
    [service sendRequest:dic];
    [self addNewService:service];
}

-(void)setVolumeMute:(id<serviceVolumeMuteDelegate>)handler isMute:(BOOL)mute
{
    NSDictionary * dic = [NSDictionary dictionaryWithObjectsAndKeys:[GlobalInfo sharedInstance].currentBaseURL,@"baseurl",[NSNumber numberWithBool:mute],@"mute", nil];
    serviceVolumeMute * service = [[serviceVolumeMute alloc] initWithDelegate:handler];
    [service sendRequest:dic];
    [self addNewService:service];
}

-(void)getWISAddress:(id<serviceGetWISAddressDelegate>)handler url:(NSString *)serverurl
{
    NSDictionary * dic = [NSDictionary dictionaryWithObjectsAndKeys:serverurl,@"serverurl", nil];
    serviceGetWISAddress * service = [[serviceGetWISAddress alloc] initWithDelegate:handler];
    [service sendRequest:dic];
    [self addNewService:service];
}

-(void)getUSBMusicList:(id<serviceGetUSBMusicListDelegate>)handler
{
    NSDictionary * dic = [NSDictionary dictionaryWithObject:[GlobalInfo sharedInstance].currentBaseURL forKey:@"baseurl"];
    serviceGetUSBMusicList * service = [[serviceGetUSBMusicList alloc] initWithDelegate:handler];
    [service sendRequest:dic];
    [self addNewService:service];
}

-(void)getUSBMusicInfo:(id<serviceGetUSBMusicInfoDelegate>)handler fileIndex:(int)index;
{
    NSDictionary * dic = [NSDictionary dictionaryWithObjectsAndKeys:[GlobalInfo sharedInstance].currentBaseURL,@"baseurl",[NSNumber numberWithInt:index],@"index", nil];
    serviceGetUSBMusicInfo * service = [[serviceGetUSBMusicInfo alloc] initWithDelegate:handler];
    [service sendRequest:dic];
    [self addNewService:service];
}

-(void)playUSBMusic:(id<servicePlayUSBMusicDelegate>)handler fileIndex:(int)index
{
    NSDictionary * dic = [NSDictionary dictionaryWithObjectsAndKeys:[GlobalInfo sharedInstance].currentBaseURL,@"baseurl",[NSNumber numberWithInt:index],@"index", nil];
    servicePlayUSBMusic * service = [[servicePlayUSBMusic alloc] initWithDelegate:handler];
    [service sendRequest:dic];
    [self addNewService:service];
}

-(void)addAudioToGroup:(id<serviceAddAudioToGroupDelegate>)handler baseURL:(NSString *)url groupName:(NSString *)group
{
    NSDictionary * dic = [NSDictionary dictionaryWithObjectsAndKeys:url,@"baseurl",group,@"group", nil];
    serviceAddAudioToGroup * service = [[serviceAddAudioToGroup alloc] initWithDelegate:handler];
    [service sendRequest:dic];
    [self addNewService:service];
}

-(void)getGroupName:(id<serviceGetGroupNameDelegate>)handler baseURL:(NSString *)url deviceName:(NSString *)name
{
    NSDictionary * dic = [NSDictionary dictionaryWithObjectsAndKeys:url,@"baseurl",name,@"name", nil];
    serviceGetGroupName * service = [[serviceGetGroupName alloc] initWithDelegate:handler];
    [service sendRequest:dic];
    [self addNewService:service];
}

-(void)playListDemo:(id<servicePlayListDemoDelegate>)handler musicURL:(NSString *)url masterIP:(NSString *)masterIP groupName:(NSArray *)deviceIPs
{
    NSDictionary * dic = [NSDictionary dictionaryWithObjectsAndKeys:url,@"baseurl",masterIP?masterIP:[GlobalInfo sharedInstance].currentBaseURL,@"master",deviceIPs?deviceIPs:[NSArray array],@"devices", nil];
    servicePlayListDemo * service = [[servicePlayListDemo alloc] initWithDelegate:handler];
    [service sendRequest:dic];
    [self addNewService:service];
}

-(void)setPlayMode:(id<serviceSetPlayModeDelegate>)handler playMode:(playmode)mode
{
    NSDictionary * dic = [NSDictionary dictionaryWithObjectsAndKeys:[GlobalInfo sharedInstance].currentBaseURL,@"baseurl",[NSNumber numberWithInt:(int)mode],@"mode", nil];
    serviceSetPlayMode * service = [[serviceSetPlayMode alloc] initWithDelegate:handler];
    [service sendRequest:dic];
    [self addNewService:service];
}

-(void)setNewDownUri:(id<serviceSetNewDownUriDelegate>)handler uri:(NSString *)uri
{
    NSDictionary * dic = [NSDictionary dictionaryWithObjectsAndKeys:[GlobalInfo sharedInstance].currentBaseURL,@"baseurl",uri,@"uri", nil];
    serviceSetNewDownUri * service = [[serviceSetNewDownUri alloc] initWithDelegate:handler];
    [service sendRequest:dic];
    [self addNewService:service];
}

-(void)setImNewDownUri:(id<serviceSetNewImDownUriDelegate>)handler uri:(NSString *)uri
{
    NSDictionary * dic = [NSDictionary dictionaryWithObjectsAndKeys:[GlobalInfo sharedInstance].currentBaseURL,@"baseurl",uri,@"uri", nil];
    serviceSetNewImDownUri * service = [[serviceSetNewImDownUri alloc] initWithDelegate:handler];
    [service sendRequest:dic];
    [self addNewService:service];
}

-(void)getToDownloadList:(id<serviceGetToDownListDelegate>)handler page:(int)page
{
    NSDictionary * dic = [NSDictionary dictionaryWithObjectsAndKeys:[GlobalInfo sharedInstance].currentBaseURL,@"baseurl",[NSNumber numberWithInt:page],@"page", nil];
    serviceGetToDownList * service = [[serviceGetToDownList alloc] initWithDelegate:handler];
    [service sendRequest:dic];
    [self addNewService:service];
}

-(void)getDownFinishedList:(id<serviceGetDownFinishedListDelegate>)handler page:(int)page
{
    NSDictionary * dic = [NSDictionary dictionaryWithObjectsAndKeys:[GlobalInfo sharedInstance].currentBaseURL,@"baseurl",[NSNumber numberWithInt:page],@"page", nil];
    serviceGetDownFinishedList * service = [[serviceGetDownFinishedList alloc] initWithDelegate:handler];
    [service sendRequest:dic];
    [self addNewService:service];
}

-(void)getDownloadingStatus:(id<serviceGetDowningStatusDelegate>)handler
{
    NSDictionary * dic = [NSDictionary dictionaryWithObjectsAndKeys:[GlobalInfo sharedInstance].currentBaseURL,@"baseurl", nil];
    serviceGetDowningStatus * service = [[serviceGetDowningStatus alloc] initWithDelegate:handler];
    [service sendRequest:dic];
    [self addNewService:service];
}

-(void)setDownloadCmd:(id<serviceSetDownCmdDelegate>)handler cmd:(NSString *)cmd
{
    NSDictionary * dic = [NSDictionary dictionaryWithObjectsAndKeys:[GlobalInfo sharedInstance].currentBaseURL,@"baseurl",cmd,@"cmd", nil];
    serviceSetDownCmd * service = [[serviceSetDownCmd alloc] initWithDelegate:handler];
    [service sendRequest:dic];
    [self addNewService:service];
}

-(void)deleteDownloadItem:(id<serviceDelDownloadItemDelegate>)handler listIndex:(int)listIndex controlFlag:(int)flag uri:(NSString *)uri
{
    NSDictionary * dic = [NSDictionary dictionaryWithObjectsAndKeys:[GlobalInfo sharedInstance].currentBaseURL,@"baseurl",@(listIndex),@"listIndex",@(flag),@"controlFlag",uri,@"uri", nil];
    serviceDelDownloadItem * service = [[serviceDelDownloadItem alloc] initWithDelegate:handler];
    [service sendRequest:dic];
    [self addNewService:service];
}

-(void)setMusicSyncDownload:(id<serviceMusicSyncDownDelegate>)handler isEnable:(BOOL)enabled
{
    NSDictionary * dic = [NSDictionary dictionaryWithObjectsAndKeys:[GlobalInfo sharedInstance].currentBaseURL,@"baseurl",[NSNumber numberWithBool:enabled],@"mute", nil];
    serviceMusicSyncDown * service = [[serviceMusicSyncDown alloc] initWithDelegate:handler];
    [service sendRequest:dic];
    [self addNewService:service];
}

#pragma mark - service control methods
-(void)removeService:(serviceInterfaceTemplate *)service
{
    dispatch_async(dispatch_get_main_queue(), ^{
        if(service == nil) return;
        dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);
        [serviceArray removeObject:service];
        dispatch_semaphore_signal(semaphore);
    });
}

-(void)removeHandler:(NSObject *)handler
{
    dispatch_async(dispatch_get_main_queue(), ^{
        dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);
        for(serviceInterfaceTemplate * service in serviceArray)
        {
            if(service.m_serviceHandler == handler)
            {
                [service allOver];
            }
        }
        dispatch_semaphore_signal(semaphore);
    });
}

-(void)stopAllServices
{
    dispatch_async(dispatch_get_main_queue(), ^{
        dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);
        for(serviceInterfaceTemplate * service in serviceArray)
        {
            [service allOver];
        }
        
        [serviceArray removeAllObjects];
        dispatch_semaphore_signal(semaphore);
    });
}

-(void)addNewService:(id)service
{
    dispatch_async(dispatch_get_main_queue(), ^{
        dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);
        [serviceArray addObject:service];
        dispatch_semaphore_signal(semaphore);
    });
}

#pragma mark - HTTPServer
-(void)startHTTPServer
{
    httpServer = [[HTTPServer alloc] init];
    [httpServer setType:@"_http._tcp."];
    
    // Serve files from our embedded Web folder
    NSURL *url = [[[NSFileManager defaultManager] URLsForDirectory:NSDocumentDirectory inDomains:NSUserDomainMask] lastObject];
    NSString *webPath = url.path;
    NSLog(@"Setting document root: %@", webPath);
    //        [httpServer setPort:[HTTPSERVERR_PORT intValue]];
    
    [httpServer setDocumentRoot:webPath];
    
    NSError *error;
    if([httpServer start:&error])
    {
        NSLog(@"Started HTTP Server on port %hu", [httpServer listeningPort]);
        _localPort = [httpServer listeningPort];
    }
    else
    {
        NSLog(@"Error starting HTTP Server: %@", error);
    }
}

-(void)stopHTTPServer
{
    [httpServer stop];
}

-(BOOL)checkIfIPChanged
{
    int addr[32] = {0};
    int number = 0;
    if([[UIDevice currentDevice].model rangeOfString:@"Simulator"].location != NSNotFound)
    {
        number = GetIPAddresses(addr);
    }
    else
    {
        number = GetWifiIPAddresses(addr);
    }
    struct in_addr ia;
    if(number == 0)
    {
        return YES;
    }
    ia.s_addr = addr[0];
    NSString * ipStr = [NSString stringWithFormat:@"%s",inet_ntoa(ia)];
    
    if([ipStr isEqualToString:self.localIP])
    {
        return NO;
    }
    
    self.localIP = ipStr;

    return YES;
}

- (void)convertToUserUUID
{
    NSUserDefaults *user = [NSUserDefaults standardUserDefaults];
    self.curOperationDeviceUUID = [user objectForKey:@"device"];
    NSLog(@"curOperationDeviceUUID:%@",self.curOperationDeviceUUID);
}

@end
